import { useEffect, useState } from 'react';
import {
  httpApi,
  CommandDialog,
  BaseCommand,
  getQueryParam,
  QueryParamKeys,
} from '@amcax/base';
import i18n from 'i18next';
import {
  Box,
  Button,
  FormControl,
  FormGroup,
  InputAdornment,
  InputLabel,
  MenuItem,
  Select,
  TextField,
} from '@mui/material';
import { wsApi } from '../../../../server/wsApi';
import { getAirfoilVertexes } from '../cmd-airfoil/cmdAirfoilAPI';
import { Vector3 } from 'three';
import { ctx2, userEvents } from '../../../../module';

const documentId = getQueryParam<string>(QueryParamKeys.DOCUMENT_ID);
const doExport = async (format: string) => {
  const { data } = await httpApi.getExportPath(documentId, format);
  const { path, dl } = data;
  const params = {
    t: path,
    o: [],
  };
  if (format === 'dxf' || format === 'step') {
    await wsApi.exportModel(params);
    window.open(dl);
  }

  ctx2.viewer.sceneSetup.fit2DView();
};

const exportShells = async (format: string) => {
  doExport(format);
};

// 导出txt文件
const exportTxtFile = (filename: string, content: string) => {
  // 创建一个 Blob 对象，指定 MIME 类型为 text/plain
  const blob = new Blob([content], { type: 'text/plain' });
  // 创建一个链接元素
  const link = document.createElement('a');
  link.href = URL.createObjectURL(blob);
  link.download = filename;
  // 触发点击事件以下载文件
  link.click();
  // 释放 URL 对象
  URL.revokeObjectURL(link.href);
};

// 导出翼型点列表
const exportAirfoilVertexes = async () => {
  const pointsPos = await getAirfoilVertexes();
  const lines: string[] = pointsPos.map((point) => `${point.x}, ${point.y}`);
  const content = lines.join('\n');
  const name = '翼型点列表.txt';
  exportTxtFile(name, content);
};

interface ExportDialogProps {
  title: string;
  onClose: () => void;
}

// ===============================================

function ExportDialog({ title, onClose }: ExportDialogProps) {
  const [format, setFormat] = useState('dxf');
  const [length, setLength] = useState(1.0);
  const [origin, setOrigin] = useState(1.0);

  useEffect(() => {
    const fetchAndSetSize = async () => {
      const pointsPos = await getAirfoilVertexes();
      const { xMin, xMax } = pointsPos.reduce(
        (acc, point) => ({
          xMin: Math.min(acc.xMin, point.x),
          xMax: Math.max(acc.xMax, point.x),
        }),
        { xMin: Infinity, xMax: -Infinity },
      );
      const len = Number(xMax - xMin);
      setOrigin(len);
      setLength(len);
    };
    fetchAndSetSize();
  }, []);

  const scaleAirfoil = async () => {
    const dxidJSON = await wsApi.getAppData(documentId + 'dxid');
    const dxid = JSON.parse(dxidJSON);
    const data = await getAirfoilVertexes();
    const factor = length / origin;
    const _points: [] = data.map((point: Vector3) => {
      return [point.x * factor, point.y * factor, point.z];
    });
    await wsApi.setParams(dxid, { points: _points });
  };

  const handleExecute = async () => {
    if (format === 'txt') {
      exportAirfoilVertexes();
    } else {
      await scaleAirfoil();
      exportShells(format);
    }
    onClose();
  };

  return (
    <CommandDialog
      title={title}
      onClose={onClose}
      placement='top'>
      <Box sx={{ padding: '0 10px', width: '200px', mt: '10px' }}>
        <FormGroup>
          <FormControl>
            <InputLabel id='format-select-label'>选择导出格式</InputLabel>
            <Select
              sx={{ mb: '10px' }}
              labelId='format-select-label'
              label='选择导出格式'
              size='small'
              value={format}
              onChange={(e) => {
                setFormat(e.target.value);
              }}>
              <MenuItem value='dxf'>.dxf</MenuItem>
              <MenuItem value='step'>.step</MenuItem>
              <MenuItem value='txt'>翼型点列表.txt</MenuItem>
            </Select>
          </FormControl>
          {format === 'dxf' || format === 'step' ? (
            <FormControl variant='filled'>
              <TextField
                name='x'
                label={`设置翼型长度(当前: ${origin} mm)`}
                type='number'
                inputProps={{ min: 1 }}
                size='small'
                margin='normal'
                value={length}
                onChange={(e) => {
                  setLength(Number(e.target.value));
                }}
                InputProps={{
                  endAdornment: (
                    <InputAdornment position='end'>mm</InputAdornment>
                  ),
                }}
              />
            </FormControl>
          ) : (
            <></>
          )}
          <Box
            sx={{
              padding: '5px 0',
              display: 'flex',
              justifyContent: 'flex-end',
            }}>
            <Button
              size='small'
              onClick={handleExecute}
              variant='contained'>
              导出
            </Button>
          </Box>
        </FormGroup>
      </Box>
    </CommandDialog>
  );
}

export const cmdExport: BaseCommand = {
  id: 'CmdExport',
  label: 'command.export',
  icon: 'commands/airfoil/export',
  create: (label: string, onClose: () => void) => (
    <ExportDialog
      title={i18n.t(label)}
      onClose={onClose}
    />
  ),
  initialDisabled: true,
  subscribeDisabled: (setDisabled: (disabled: boolean) => void) => {
    const listener = (empty: boolean) => {
      setDisabled(empty);
    };
    userEvents.on('sceneEmpty', listener);
    return () => userEvents.off('sceneEmpty', listener);
  },
};
